// Package jfbym 云码API
/*
	官方文档: https://www.jfbym.com/demo.html
	todo: funnelApi, funnelApiResult
*/
package jfbym

import (
	"gitee.com/kaylee595/gkaylee/kerr"
	"github.com/imroc/req/v3"
	url2 "net/url"
	"yyLogin/pkg/jfbym/common"
	"yyLogin/pkg/jfbym/customApi"
)

const defaultBaseUrl = "http://api.jfbym.com/api/YmServer/"

type Client struct {
	httpClient      *req.Client
	baseURL         *url2.URL
	token           string
	developerSecret string
}

type Option func(*Client)

func WithHttpClient(httpClient *req.Client) Option {
	return func(c *Client) {
		c.httpClient = httpClient
	}
}

// WithDeveloperSecret 开发者密钥, "人数达到3人以上并消费，我们将会把消费金额的20%作为返点。"
func WithDeveloperSecret(developerSecret string) Option {
	return func(c *Client) {
		c.developerSecret = developerSecret
	}
}

func WithBaseURL(baseURL *url2.URL) Option {
	return func(c *Client) {
		c.baseURL = baseURL
	}
}

var _, _, _ = WithHttpClient, WithDeveloperSecret, WithBaseURL

// NewClient if httpClient is nil, will use req.DefaultClient()
func NewClient(token string, options ...Option) *Client {
	c := &Client{
		baseURL:    kerr.Must(url2.Parse(defaultBaseUrl)),
		httpClient: req.DefaultClient(),
		token:      token,
	}
	for _, option := range options {
		option(c)
	}
	return c
}

// CustomApi 验证码识别接口
func (c *Client) CustomApi(i customApi.Handler) error {
	url := c.baseURL.JoinPath("customApi").String()
	payload, err := i.GenerateReqPayload()
	if err != nil {
		return kerr.WrapTraceStack(err)
	}
	payload["token"] = c.token
	payload["developer_tag"] = c.developerSecret
	resp := c.httpClient.Post(url).SetFormData(payload).Do()
	if resp.Err != nil {
		return kerr.WrapTraceStack(resp.Err)
	}
	respPayload, err := resp.ToBytes()
	if err != nil {
		return kerr.WrapTraceStack(err)
	}
	err = i.Unmarshal(respPayload)
	if err != nil {
		return kerr.WrapTraceStack(err)
	}
	return nil
}

type RespUserInfoApi struct {
	Score string `json:"score"`
}

// GetUserInfoApi 获取余额积分接口
func (c *Client) GetUserInfoApi() (*RespUserInfoApi, error) {
	url := c.baseURL.JoinPath("getUserInfoApi").String()
	resp := c.httpClient.Post(url).SetFormData(map[string]string{"token": c.token, "type": "score"}).Do()
	if resp.Err != nil {
		return nil, kerr.WrapTraceStack(resp.Err)
	}
	b := &common.RespApiBase{}
	err := resp.UnmarshalJson(b)
	if err != nil {
		return nil, kerr.WrapTraceStack(err)
	}
	if b.Code != 10001 {
		return nil, kerr.WrapTraceStack(b)
	}
	r := &RespUserInfoApi{}
	err = b.UnmarshalData(r)
	if err != nil {
		return nil, kerr.WrapTraceStack(err)
	}
	return r, nil
}

// RefundApi 报错接口, 返还积分接口
func (c *Client) RefundApi(uniqueCode string) error {
	url := c.baseURL.JoinPath("refundApi").String()
	resp := c.httpClient.Post(url).SetFormData(map[string]string{"token": c.token, "uniqueCode": uniqueCode}).Do()
	if resp.Err != nil {
		return kerr.WrapTraceStack(resp.Err)
	}
	b := &common.RespApiBase{}
	err := resp.UnmarshalJson(b)
	if err != nil {
		return kerr.WrapTraceStack(err)
	}
	if b.Code != 200 {
		return kerr.WrapTraceStack(b)
	}
	return nil
}
